package com.njtoyo.taxi.admin.service.business.driver.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.library.common.util.CopyUtil;
import com.njtoyo.taxi.admin.logic.business.driver.DriverNotifyMessageLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.Company;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverNotifyMessage;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverNotifyMessageRead;
import com.njtoyo.taxi.admin.mapper.master.enums.driverNotifyMessage.Scope;
import com.njtoyo.taxi.admin.mapper.master.enums.driverNotifyMessage.State;
import com.njtoyo.taxi.admin.mapper.master.mapper.CompanyMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverNotifyMessageMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverNotifyMessageReadMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.driver.notifyMessage.DetailPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.driver.notifyMessage.ListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.driver.notifyMessage.CreateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.driver.notifyMessage.ListWrapper;
import com.njtoyo.taxi.admin.service.business.driver.NotifyMessageService;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.njtoyo.taxi.entity.backend.Enum;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@DS(Const.PRIMARY_DS)
public class NotifyMessageServiceImpl implements NotifyMessageService {

    @Autowired
    private DriverNotifyMessageMapper driverNotifyMessageMapper;

    @Autowired
    private DriverNotifyMessageLogic driverNotifyMessageLogic;

    @Autowired
    private DriverNotifyMessageReadMapper driverNotifyMessageReadMapper;

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;
    @Autowired
    private CompanyMapper companyMapper;

    @Override
    public RestResult getList(AdminUser adminUser,  ListWrapper listWrapper) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();
        if (Objects.nonNull(listWrapper.getCompanyId())) {
            listWrapper.setDriverRegionId(null);
        }
        if (identity.getType().equals(Enum.AccountType.canton)) {
            listWrapper.setDriverRegionIds(identity.getDriverRegionIds());
        } else if (identity.getType().equals(Enum.AccountType.company)) {
            listWrapper.setCompanyIds(identity.getCompanyIds());
        }
        IPage<ListPresenter> messageList = driverNotifyMessageMapper.getList(listWrapper);
        return RestResult.success(messageList);
    }

    @Override
    public RestResult create(CreateWrapper createWrapper) {
        State sendState = createWrapper.getState();
        if (createWrapper.getScope().equals(Scope.region) && Objects.isNull(createWrapper.getDriverRegionId())) {
            return RestResult.build(ResultEnum.PARAMS_ERROR);
        }
        if (createWrapper.getScope().equals(Scope.company) && Objects.isNull(createWrapper.getCompanyId())) {
            return RestResult.build(ResultEnum.PARAMS_ERROR);
        }
        if (createWrapper.getState().equals(State.done)) {
            createWrapper.setRegularReleaseTime(DateUtil.currentSeconds());
        } else {
            if (Objects.isNull(createWrapper.getRegularReleaseTime())) {
                return RestResult.build(ResultEnum.PARAMS_ERROR);
            }
            if (createWrapper.getRegularReleaseTime() < DateUtil.currentSeconds() + 5) {
                return RestResult.failed("定时发布时间需要在当前时间之后");
            }
        }

        createWrapper.setState(State.ready);

        DriverNotifyMessage message = CopyUtil.copy(createWrapper, DriverNotifyMessage.class);
        if (Scope.company.equals(createWrapper.getScope())) {
            Company company = companyMapper.selectById(createWrapper.getCompanyId());
            message.setDriverRegionId(company.getDriverRegionId());
        }
        driverNotifyMessageMapper.insert(message);

        if (sendState.equals(State.ready)) {
            Date sendTime = new Date(message.getRegularReleaseTime() * 1000);
            taskScheduler.schedule(() -> {
                driverNotifyMessageLogic.send(message.getId());
            }, sendTime);
        } else {
            driverNotifyMessageLogic.send(message.getId());
        }
        return RestResult.success();
    }

    @Override
    public RestResult update(Long id, DriverNotifyMessage request) {
        // 判断消息是否存在
        DriverNotifyMessage item = driverNotifyMessageMapper.selectById(id);
        if (Objects.isNull(item)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        request.setId(id);

        // 如果存在标题，则校验+赋值
        if (StringUtils.hasText(request.getTitle()) && request.getTitle().length() > 64) {
            return RestResult.failed("标题最多为64个字");
        }

        // 如果存在语音内容，则校验+赋值
        if (StringUtils.hasText(request.getVoiceContent()) && request.getVoiceContent().length() > 140) {
            return RestResult.failed("语音内容最多为140个字");
        }

        // 如果存在详情摘要，则校验+赋值
        if (StringUtils.hasText(request.getDetailDigest()) && request.getDetailDigest().length() > 120) {
            return RestResult.failed("详情摘要最多为120个字");
        }

        // 判断消息是否已发送
        /*
         * 已发送，则只能修改消息内容[title,voice_content,priority_category,head_image,detail_digest,detail,media_category]
         * 不可修改[driver_region_id,company_id,scope,regular_release_time,state,created_at,updated_at]
         * 未发送，可以修改全部
         */
        if (item.getState().equals(State.done)) {
            request.setDriverRegionId(item.getDriverRegionId());
            request.setCompanyId(item.getCompanyId());

            request.setScope(null);
            request.setRegularReleaseTime(null);
            request.setState(null);
            request.setCreatedAt(null);
            request.setUpdatedAt(null);
        } else if (item.getState().equals(State.ready)) {
            // 如果设置区域范围则校验
            if (request.getScope().equals(Scope.region)) {
                if (Objects.isNull(request.getDriverRegionId())) {
                    return RestResult.build(ResultEnum.PARAMS_ERROR);
                }
                // 设公司为null
                request.setCompanyId(null);
            }

            // 如果设置公司范围则校验
            if (request.getScope().equals(Scope.company)) {
                if (Objects.isNull(request.getCompanyId())) {
                    return RestResult.build(ResultEnum.PARAMS_ERROR);
                }
                // 设区域为null
                Company company = companyMapper.selectById(request.getCompanyId());
                request.setDriverRegionId(company.getDriverRegionId());
                request.setDriverRegionId(null);
            }

            // 校验发布状态
            if (Objects.nonNull(request.getState())) {
                // 立即发送
                if (request.getState().equals(State.done)) {
                    request.setRegularReleaseTime((new Date()).getTime() / 1000);
                } else if (request.getState().equals(State.ready)) {
                    // 定时发送
                    if (Objects.isNull(request.getRegularReleaseTime())) {
                        return RestResult.build(ResultEnum.PARAMS_ERROR);
                    } else if (request.getRegularReleaseTime() < DateUtil.currentSeconds() + 5) {
                        return RestResult.failed("定时发布时间需要在当前时间之后");
                    }
                }
            }
        }

        // 修改
        driverNotifyMessageMapper.updateById(request);

        if (item.getState().equals(State.ready)) {
            if (request.getState().equals(State.ready) && !item.getRegularReleaseTime().equals(request.getRegularReleaseTime())) {
                Date sendTime = new Date(request.getRegularReleaseTime() * 1000);
                taskScheduler.schedule(() -> {
                    driverNotifyMessageLogic.send(id);
                }, sendTime);
            } else if (request.getState().equals(State.done)) {
                driverNotifyMessageLogic.send(id);
            }
        }

        return RestResult.success();
    }

    @Override
    @Transactional
    public RestResult delete(Long id) {
        // 判断消息是否存在
        DriverNotifyMessage item = driverNotifyMessageMapper.selectById(id);
        if (Objects.isNull(item)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        // 删除消息+read
        driverNotifyMessageMapper.deleteById(id);
        QueryWrapper<DriverNotifyMessageRead> wrapper = new QueryWrapper<>();
        driverNotifyMessageReadMapper.delete(wrapper.eq("message_id", id));

        return RestResult.success();
    }

    @Override
    public RestResult getDetail(Long id) {
        // 判断消息是否存在
        DriverNotifyMessage item = driverNotifyMessageMapper.selectById(id);
        if (Objects.isNull(item)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        DetailPresenter result = driverNotifyMessageMapper.getDetail(id);
        return RestResult.success(result);
    }
}
